package com.qm.console.es.bo;

import org.apache.commons.lang3.StringUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * //                       _oo0oo_
 * //                      o8888888o
 * //                      88" . "88
 * //                      (| -_- |)
 * //                      0\  =  /0
 * //                    ___/`---'\___
 * //                  .' \\|     |// '.
 * //                 / \\|||  :  |||// \
 * //                / _||||| -:- |||||- \
 * //               |   | \\\  -  /// |   |
 * //               | \_|  ''\---/''  |_/ |
 * //               \  .-\__  '-'  ___/-. /
 * //             ___'. .'  /--.--\  `. .'___
 * //          ."" '<  `.___\_<|>_/___.' >' "".
 * //         | | :  `- \`.;`\ _ /`;.`/ - ` : | |
 * //         \  \ `_.   \_ __\ /__ _/   .-` /  /
 * //     =====`-.____`.___ \_____/___.-`___.-'=====
 * //                       `=---='
 * //
 * //
 * //     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * //
 * //               佛祖保佑         永无BUG
 * <p>
 * com.qm.console.es
 * Created on 2021/6/15.
 */
public class DateOffset {

   private static final Pattern sExpPattern = Pattern.compile("([\\+\\-])(\\d+)([ymdHMp])");

   private int plusMultiplier;
   private int period;
   private String unit;

   public DateOffset(String expression) {
      Matcher matcher = sExpPattern.matcher(expression);
      if (matcher.find()){
         plusMultiplier = StringUtils.equals(matcher.group(1), "+") ? 1 : -1;
         period = Integer.parseInt(matcher.group(2));
         unit = matcher.group(3);

      } else {
         throw new IllegalArgumentException(String.format("bad expression: %s", expression));
      }
   }

   public Date apply(Date src) {
      return apply(src, 0);
   }

   public Date apply(Date src, long periodLength) {
      if (StringUtils.equals(unit, "p")) {
         if (periodLength == 0) {
            throw new IllegalArgumentException(String.format("bad period length: %s", periodLength));
         }
         return Date.from(src.toInstant().plusSeconds(plusMultiplier * periodLength * period));
      } else {
         Calendar calendar = Calendar.getInstance();
         calendar.setTime(src);
         calendar.add(getField(), plusMultiplier * period);
         return calendar.getTime();
      }
   }

   private int getField() {
      if (StringUtils.equals(unit, "y")) {
         return Calendar.YEAR;
      } else if (StringUtils.equals(unit, "m")) {
         return Calendar.MONTH;
      } else if (StringUtils.equals(unit, "d")) {
         return Calendar.DATE;
      } else if (StringUtils.equals(unit, "H")) {
         return Calendar.HOUR;
      } else if (StringUtils.equals(unit, "M")) {
         return Calendar.MINUTE;
      } else {
         // won't be here..
         return -1;
      }
   }



}
